/**
  ******************************************************************************
  * @file       bsp_usart.c
  * @author     embedfire
  * @version     V1.0
  * @date        2024
  * @brief   重定向C库printf函数到usart端口
  ******************************************************************************
  * @attention
  *
  * 实验平台  ：野火 STM32F103C8T6-STM32开发板 
  * 论坛      ：http://www.firebbs.cn
  * 官网      ：https://embedfire.com/
  * 淘宝      ：https://yehuosm.tmall.com/
  *
  ******************************************************************************
  */
  
  
#include "usart/bsp_usart.h"

USART_DataTypeDef debug_receive_data = {0};
USART_DataTypeDef rd03_receive_data = {0};


/**
  * @brief  配置USARTX中断配置
  * @param  无
  * @retval 无
  */
void USARTX_NVIC_Config(void)
{

    // 配置中断优先级
    NVIC_InitTypeDef nvic_initstructure;
#if 1
    nvic_initstructure.NVIC_IRQChannel = DEBUG_IRQ;
    nvic_initstructure.NVIC_IRQChannelPreemptionPriority = 1;
    nvic_initstructure.NVIC_IRQChannelSubPriority = 1;
    nvic_initstructure.NVIC_IRQChannelCmd = ENABLE;
    
    NVIC_Init(&nvic_initstructure);
    
    
#endif
    
#if 1
    nvic_initstructure.NVIC_IRQChannel = RD03_IRQ;
    nvic_initstructure.NVIC_IRQChannelPreemptionPriority = 0;
    nvic_initstructure.NVIC_IRQChannelSubPriority = 0;
    nvic_initstructure.NVIC_IRQChannelCmd = ENABLE;
    
    NVIC_Init(&nvic_initstructure);
     
#endif
}

/**
 * @brief  配置USARTX模式
 * @param  无
 * @retval 无
 */
void USARTX_Mode_Config(void)
{
  
    /* 定义一个USART结构体 */
    USART_InitTypeDef usart_initstruct = {0};
#if 1  
    /* 开启USART相关的GPIO外设/端口时钟 */
    DEBUG_APBXCLKCMD(DEBUG_USARTX_CLK_PORT,ENABLE);

    /* 配置串口的工作参数 */
    usart_initstruct.USART_BaudRate                 =  DEBUG_BAUDRATE;                      //配置波特率
    usart_initstruct.USART_HardwareFlowControl      =  USART_HardwareFlowControl_None;  //配置硬件流控制
    usart_initstruct.USART_Mode                     =  USART_Mode_Tx|USART_Mode_Rx;     //配置工作模式
    usart_initstruct.USART_Parity                   =  USART_Parity_No;                 //配置校验位    
    usart_initstruct.USART_StopBits                 =  USART_StopBits_1;                //配置停止位
    usart_initstruct.USART_WordLength               =  USART_WordLength_8b;             //配置帧数据字长
    
    USART_Init(DEBUG_USARTX, &usart_initstruct);
    
    USART_ITConfig(DEBUG_USARTX,USART_IT_RXNE,ENABLE);              //开启串口数据接收中断
    USART_ITConfig(DEBUG_USARTX,USART_IT_IDLE,ENABLE);              //开启串口数据空闲中断
  
#endif
    
#if 1  
    /* 开启USART相关的GPIO外设/端口时钟 */
    RD03_APBXCLKCMD(RD03_USARTX_CLK_PORT,ENABLE);

    /* 配置串口的工作参数 */
    usart_initstruct.USART_BaudRate                 =  RD03_BAUDRATE;                  //配置波特率
    usart_initstruct.USART_HardwareFlowControl      =  USART_HardwareFlowControl_None;  //配置硬件流控制
    usart_initstruct.USART_Mode                     =  USART_Mode_Tx|USART_Mode_Rx;     //配置工作模式
    usart_initstruct.USART_Parity                   =  USART_Parity_No;                 //配置校验位    
    usart_initstruct.USART_StopBits                 =  USART_StopBits_1;                //配置停止位
    usart_initstruct.USART_WordLength               =  USART_WordLength_8b;             //配置帧数据字长
    
    USART_Init(RD03_USARTX, &usart_initstruct);
    
    USART_ITConfig(RD03_USARTX,USART_IT_RXNE,ENABLE);//开启串口数据接收中断
    USART_ITConfig(RD03_USARTX,USART_IT_IDLE,ENABLE);//开启串口数据空闲中断
  
#endif
    
}

/**
 * @brief  USARTX初始化
 * @param  无
 * @retval 无
 */
void USARTX_Init(void)
{
    /* 配置USARTX中断配置 */
    USARTX_NVIC_Config();
    
    /* 配置USARTX模式 */
    USARTX_Mode_Config();

    /* 对应的GPIO的配置 */
    DEBUG_GPIO_Config();
    RD03_GPIO_Config();
    
    /* 使能串口 */
    USART_Cmd(DEBUG_USARTX,ENABLE);
    USART_Cmd(RD03_USARTX,ENABLE);


}


/**
 * @brief 发送一个字节函数
 * @param pusartx：USARTx(x=1,2,3)/UARTx(x=4,5) 
 * @param ch:要发送的数据
 * @note  无
 * @retval 无
 */
void USARTX_SendByte(USART_TypeDef *pusartx, uint8_t ch)
{
    /* 发送一个字节数据到USART */
    USART_SendData(pusartx,ch);
    /* 等待发送数据寄存器为空 */
    while (USART_GetFlagStatus(pusartx, USART_FLAG_TXE) == RESET);

}

/**
 * @brief 发送8位的数组函数
 * @param pusartx：USARTx(x=1,2,3)/UARTx(x=4,5)  
 * @param array:要发送的数组
 * @param num:数组大小
 * @note  无
 * @retval 无
 */
void USARTX_SendArray(USART_TypeDef *pusartx, uint8_t *array, uint16_t num)
{
    uint8_t i;
    for (i = 0; i < num; i++)
    {
        /* 发送一个字节数据到USART */
        USARTX_SendByte(pusartx, array[i]);
    }
    
    /* 等待发送完成 */
    while (USART_GetFlagStatus(pusartx, USART_FLAG_TC) == RESET);
    
}

/**
 * @brief 发送一个16位数函数
 * @param pusartx：USARTx(x=1,2,3)/UARTx(x=4,5) 
 * @param data:要发送的数据
 * @note  无
 * @retval 无
 */
void USARTX_SendHalfWord(USART_TypeDef *pusartx, uint16_t ch)
{
    uint8_t temp_h, temp_l;

    /* 取出高八位 */
    temp_h = (ch & 0XFF00) >> 8;
    /* 取出低八位 */
    temp_l = ch & 0XFF;

    /* 发送高八位 */
    USART_SendData(pusartx, temp_h);
    while (USART_GetFlagStatus(pusartx, USART_FLAG_TXE) == RESET);

    /* 发送低八位 */
    USART_SendData(pusartx, temp_l);
    while (USART_GetFlagStatus(pusartx, USART_FLAG_TXE) == RESET);
}

/**
 * @brief 发送字符串函数
 * @param pusartx：USARTx(x=1,2,3)/UARTx(x=4,5) 
 * @param str:要发送的数据
 * @note  无
 * @retval 无
 */
void USARTX_SendString(USART_TypeDef *pusartx, uint8_t *str)
{
    unsigned int k = 0;
    do
    {
        USARTX_SendByte(pusartx, *(str + k));
        k++;
    } while (*(str + k) != '\0');

    /* 等待发送完成 */
    while (USART_GetFlagStatus(pusartx, USART_FLAG_TC) == RESET);
}

/**
 * @brief 发送指定长度字符串函数
 * @param pusartx：USARTx(x=1,2,3)/UARTx(x=4,5) 
 * @param str:要发送的数据
 * @note  无
 * @retval 无
 */
void USARTX_SendString_Lenth(USART_TypeDef *pusartx, uint8_t *str,uint32_t num)
{
    unsigned int k = 0;
    do
    {
        USARTX_SendByte(pusartx, *(str + k));
        k++;
    } while (k<num);

    /* 等待发送完成 */
    while (USART_GetFlagStatus(pusartx, USART_FLAG_TC) == RESET);
}

/**
 * @brief 将一个字符写入到文件中,重定向c库函数printf到串口，重定向后可使用printf函数
 * @param ch: 要写入的字符
 * @param f: 指向FILE结构的指针
 * @note  无
 * @retval 成功，返回该字符
 */
int fputc(int ch, FILE *f)
{
    /* 发送一个字节数据到串口 */
    USART_SendData(DEBUG_USARTX, (uint8_t)ch);
    /* 等待发送完成 */
    while (USART_GetFlagStatus(DEBUG_USARTX, USART_FLAG_TC) == RESET);
    return (ch);
}

/**
 * @brief 重定向c库函数scanf到串口DEBUG_USART，重写向后可使用scanf、getchar等函数
 * @param f: 指向FILE结构的指针
 * @note  无
 * @retval 成功，返回该字符
 */
int fgetc(FILE *f)
{
    /* 等待接收完成 */
    while (USART_GetFlagStatus(DEBUG_USARTX, USART_FLAG_RXNE) == RESET);
    return ((int)USART_ReceiveData(DEBUG_USARTX));
}





/*****************************END OF FILE***************************************/

